package com.icesoft.base.manager.security.login.phone;

import com.icesoft.base.manager.security.config.SecurityConst;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author 手机号登录验证filter
 */
public class PhoneAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    private static final String SPRING_SECURITY_FORM_PHONE_KEY = "phone";
    @Setter
    private String phoneParameter = SPRING_SECURITY_FORM_PHONE_KEY;
    @Setter
    private String smsCodeParameter = "smsCode";

    public PhoneAuthenticationFilter() {
        super(new AntPathRequestMatcher(SecurityConst.PHONE_LOGIN_PROCESS_API, "POST"));
    }

    @Override
    @SneakyThrows
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) {
        boolean postOnly = true;
        if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }

        String phone = obtainMobile(request);

        if (phone == null) {
            phone = "";
        }

        phone = phone.trim();
        String smsCode = obtainSmsCode(request);

        PhoneAuthenticationToken phoneAuthenticationToken = new PhoneAuthenticationToken(phone, smsCode);

        setDetails(request, phoneAuthenticationToken);
        return this.getAuthenticationManager().authenticate(phoneAuthenticationToken);
    }

    private String obtainMobile(HttpServletRequest request) {
        return request.getParameter(phoneParameter);
    }

    private String obtainSmsCode(HttpServletRequest request) {
        return request.getParameter(smsCodeParameter);
    }

    private void setDetails(HttpServletRequest request,
                            PhoneAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}

